from docutils import frontend
frontend.OptionParser.get_standard_config_files = lambda self: ()
import docutils.core as docutils_core
from docutils import nodes
from docutils.parsers import rst
from docutils.parsers.rst import directives
import core
import render


# Disallow file insertion and raw insertion directives
# See http://docutils.sourceforge.net/docs/howto/security.html
# Unfortunately this breaks the way we currently implement interweaving.
SETTINGS_OVERRIDES = dict(
    file_insertion_enabled=0,
    raw_enabled=0,
    stylesheet_path=None,
    )


class MinervaEmbedDirective(rst.Directive):
  """
  """
  required_arguments = 1
  optional_arguments = 0
  final_argument_whitespace = False
  option_spec = {}
  has_content = True

  def run(self):
    if not self.state.document.settings.raw_enabled:
      raise self.warning('"%s" directive disabled.' % self.name)

    attributes = {'format': 'html'}
    encoding = self.options.get(
        'encoding', self.state.document.settings.input_encoding)
    path = directives.uri(self.arguments[0])
    attributes['source'] = path
    # Get content at path
    noun = core.Noun.Find(path)
    if not noun:
      raise self.error('Error in Minerva directive: "%s" does not exist' % path)

    content_html = noun.content.Html(embed=True)

    raw_node = nodes.raw('', content_html, **attributes)
    return [raw_node]


directives.register_directive('noun', MinervaEmbedDirective)


class Plugin(core.ContentType):
  """A ReStructuredText Content.

  These form the basis for documents and can embed any of the other
  Content types.
  """

  @classmethod
  def Customize(cls, content, src, **kwargs):
    content.src = src

  @classmethod
  def Html(cls, content, editor=False, **kwargs):
    template_dir = 'content_types'
    template_name = cls.name + '.html'

    if content and content.src:
      parts = docutils_core.publish_parts(
          content.src, writer_name='html',
          settings_overrides=SETTINGS_OVERRIDES)
      kwargs['content_html'] = parts['html_body']

    return render.Render(
        template_dir, template_name, content_type=cls, content=content,
        editor=editor, **kwargs)
